package app.maker.metier.ticketImpl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import app.maker.entity.Ticket;
import app.maker.entity.TicketHasUser;
import app.maker.entity.User;
import app.maker.error.TicketException;
import app.maker.error.UserException;
import app.maker.metier.ticketIntf.IGestionTicket;
import app.maker.ticket.intf.ITicket;
import app.maker.user.intf.IUser;

@Stateless(mappedName="gestionTicket")
public class GestionTicket implements IGestionTicket {
	@EJB
	private ITicket iticket;

	@EJB
	private IUser iuser;

	private String returnDate(Date maDate) {
		SimpleDateFormat formater = null;
		formater = new SimpleDateFormat("yyyyMMddHHmmss");
		return formater.format(maDate);
	}

	private String genereReference(Date maDate) {
		String ref = "TIC" + returnDate(maDate);
		return ref;
	}

	private void creerTicketMoteur (Ticket monTicket, User source, User pilote, Date maDate, String ref) throws UserException, TicketException {

		User sourceBD = this.iuser.getUserByLogin(source.getLogin());
		User piloteBD = this.iuser.getUserByLogin(pilote.getLogin());

		
		if (this.iuser.getUser(sourceBD.getId()) == null) {
			throw new UserException("La source n'a pas été trouvée lors de la création du ticket!");
		}

		if (this.iuser.getUser(piloteBD.getId()) == null) {
			throw new UserException("Le pilote n'a pas été trouvée lors de la création du ticket!");
		}

		if (monTicket.getDescription() == null) {
			throw new TicketException("Les descriptions du ticket ne peuvent pas être vides!");
		}

		monTicket.setDate(maDate);
		monTicket.setReference(ref);

		
		this.iticket.updateTicket(monTicket);
		
		if(monTicket.getCategorie() == null) {
			monTicket.setCategorie("");
		}

		
		
		Ticket ticketBD = this.iticket.getTicketByReference(ref);
		if(ticketBD  == null) {
			System.out.println("grrrrrrrrrrrr!!!");
		}
		
		TicketHasUser thuSource = new TicketHasUser();
		thuSource.setUser(sourceBD);
		thuSource.setDate(maDate);
		thuSource.setSource((byte) 1);
		thuSource.setEtat("NOUVEAU");
		thuSource.setTicket(ticketBD);

		TicketHasUser thuPilote = new TicketHasUser();
		thuPilote.setUser(piloteBD);
		thuPilote.setDate(maDate);
		thuPilote.setSource((byte) 0);
		thuPilote.setEtat("NOUVEAU");
		thuPilote.setTicket(ticketBD);
		
		List<TicketHasUser> liste1 = new ArrayList<TicketHasUser>();
		List<TicketHasUser> liste2 = new ArrayList<TicketHasUser>();
		liste1.add(thuSource);
		liste2.add(thuPilote);		
		
		sourceBD.setTicketHasUsers(liste1);
		piloteBD.setTicketHasUsers(liste2);
		iuser.updateUser(piloteBD);
		iuser.updateUser(sourceBD);		
		
	}

	public void creerTicket(Ticket nvTicket, User source, User pilote) throws UserException, TicketException {
		Date maDate = new Date();
		String ref = genereReference(maDate);
		creerTicketMoteur (nvTicket, source, pilote, maDate, ref);
	}

	public void creerTicket(Ticket nvTicket, User source, User pilote, Date maDate, String ref) throws UserException, TicketException {
		creerTicketMoteur (nvTicket, source, pilote, maDate, ref);
	}

	public void modifierTicket(Ticket monTicket, User userSource, User userPilote) throws TicketException, UserException {
		if (monTicket.getTravauxEffectues() != null) {
			User sourceBD = this.iuser.getUserByLogin(userSource.getLogin());
			User piloteBD = this.iuser.getUserByLogin(userPilote.getLogin());
			Ticket ticketBD = this.iticket.getTicketByReference(monTicket.getReference());

			TicketHasUser source = new TicketHasUser();
			source.setUser(sourceBD);
			source.setDate(new Date());
			source.setSource((byte) 0);
			source.setEtat("EN_COURS");
			source.setTicket(ticketBD);

			TicketHasUser pilote = new TicketHasUser();
			pilote.setUser(piloteBD);
			pilote.setDate(new Date());
			pilote.setSource((byte) 0);
			pilote.setEtat("EN_COURS");
			pilote.setTicket(ticketBD);

			List<TicketHasUser> nouvelleListe = ticketBD.getTicketHasUsers();
			nouvelleListe.add(source);
			nouvelleListe.add(pilote);
			
			
			ticketBD.setTicketHasUsers(nouvelleListe);
			iticket.updateTicket(ticketBD);
		} else {
			throw new TicketException("Aucune modification effectuée sur le ticket " + monTicket.getReference() + " !");
		}
	}

	public void terminerTicket(Ticket monTicket, User user) throws TicketException, UserException {
		User userBD = this.iuser.getUserByLogin(user.getLogin());
		
		if (this.iuser.getUser(userBD.getId()) == null) {
			throw new UserException("La source n'a pas été trouvée lors de la création du ticket!");
		}

		Ticket ticketBD = this.iticket.getTicketByReference(monTicket.getReference());
		
		List<TicketHasUser> listeAssociations = ticketBD.getTicketHasUsers();
		TicketHasUser dernierAsso = listeAssociations.get(listeAssociations.size() - 1);
		if (dernierAsso.getEtat().compareTo("EN_COURS") != 0) {
			throw new TicketException("Le ticket ne peut être passé en l'état demandé!");
		}


		TicketHasUser pilote = new TicketHasUser();
		pilote.setUser(userBD);
		pilote.setDate(new Date());
		pilote.setSource((byte) 0);
		pilote.setEtat("TERMINER_A_VALIDER");
		pilote.setTicket(ticketBD);

		List<TicketHasUser> nouvelleListe = ticketBD.getTicketHasUsers();
		nouvelleListe.add(pilote);
		ticketBD.setTicketHasUsers(nouvelleListe);
		iticket.updateTicket(ticketBD);
	}

	public void validerTicket(Ticket monTicket, User user) throws TicketException, UserException {
		User userBD = this.iuser.getUserByLogin(user.getLogin());

		if (this.iuser.getUser(userBD.getId()) == null) {
			throw new UserException("La source n'a pas été trouvée lors de la création du ticket!");
		}

		Ticket ticketBD = this.iticket.getTicketByReference(monTicket.getReference());
		List<TicketHasUser> listeAssociations = ticketBD.getTicketHasUsers();
		TicketHasUser dernierAsso = listeAssociations.get(listeAssociations.size() - 1);
		if (dernierAsso.getEtat().compareTo("TERMINER_A_VALIDER") != 0) {
			throw new TicketException("Le ticket ne peut être passé en l'état demandé!");
		}

		TicketHasUser userSource = listeAssociations.get(1);
		if (userSource.getUser().getId() != userBD.getId()) {
			throw new UserException("L'utilisateur n'est pas la source du ticket et ne peut pas valider le ticket " + monTicket.getReference() + " !");
		}

		TicketHasUser pilote = new TicketHasUser();
		pilote.setUser(userBD);
		pilote.setDate(new Date());
		pilote.setSource((byte) 0);
		pilote.setEtat("VALIDER");
		pilote.setTicket(ticketBD);
		
		List<TicketHasUser> nouvelleListe = ticketBD.getTicketHasUsers();
		nouvelleListe.add(pilote);
		ticketBD.setTicketHasUsers(nouvelleListe);
		iticket.updateTicket(ticketBD);

	}

	public void invaliderTicket(Ticket monTicket, User user) throws UserException, TicketException {
		User userBD = this.iuser.getUserByLogin(user.getLogin());
		
		if (this.iuser.getUser(userBD.getId()) == null) {
			throw new UserException("La source n'a pas été trouvée lors de la création du ticket!");
		}

		Ticket ticketBD = this.iticket.getTicketByReference(monTicket.getReference());
		List<TicketHasUser> listeAssociations = ticketBD.getTicketHasUsers();
		TicketHasUser dernierAsso = listeAssociations.get(listeAssociations.size() - 1);
		if (dernierAsso.getEtat().compareTo("TERMINER_A_VALIDER") != 0) {
			throw new TicketException("Le ticket ne peut être passé en l'état demandé!");
		}

		TicketHasUser userSource = listeAssociations.get(1);
		if (userSource.getUser().getId() != userBD.getId()) {
			throw new UserException("L'utilisateur n'est pas la source du ticket et ne peut pas valider le ticket " + monTicket.getReference() + " !");
		}

		TicketHasUser pilote = new TicketHasUser();
		pilote.setUser(userBD);
		pilote.setDate(new Date());
		pilote.setSource((byte) 0);
		pilote.setEtat("INVALIDER");
		pilote.setTicket(ticketBD);

		List<TicketHasUser> nouvelleListe = ticketBD.getTicketHasUsers();
		nouvelleListe.add(pilote);
		ticketBD.setTicketHasUsers(nouvelleListe);

		List<TicketHasUser> listAllUsers = ticketBD.getTicketHasUsers();

		User piloteBD = listAllUsers.get(0).getUser();
		
		creerTicket(ticketBD, userBD, piloteBD, ticketBD.getDate(), ticketBD.getReference());

	}

	public void supprimerTicket(Ticket ticket, User user) throws TicketException, UserException {
		User userBD = this.iuser.getUserByLogin(user.getLogin());
		
		if (userBD.getRole() != 0) {
			throw new UserException("L'utilisateur n'a pas les droits administrateur !");
		}
		Ticket ticketBD = this.iticket.getTicketByReference(ticket.getReference());
		iticket.deleteTicket(ticketBD);
	}

	public Ticket consulterTicket(String reference) throws TicketException {
		Ticket ticketBD = this.iticket.getTicketByReference(reference);
		return iticket.getTicket(ticketBD.getIdTicket());
	}
	
	public List<Ticket> getAllTicketsBD() throws TicketException {
		ArrayList<Ticket> allTickets = (ArrayList<Ticket>) this.iticket.getAllTicket();
		return allTickets;
	}
	
	public User getSource(int idTicket) throws TicketException {
		List<TicketHasUser> liste = iticket.getTicket(idTicket)
				.getTicketHasUsers();
		for (TicketHasUser tu : liste) {
			if (tu.getSource() == 1)
				return tu.getUser();
		}
		return null;
	}

}
